package com.xbongbong.pro.aiassistant.abstracts;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.SizeConstant;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.help.UserAndDepartmentHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.aiassistant.AiAssistantConditionHelp;
import com.xbongbong.pro.aiassistant.manager.feign.BusinessFeignClient;
import com.xbongbong.pro.aiassistant.service.SsDistributeSaveService;
import com.xbongbong.pro.aiassistant.service.SsHistoryService;
import com.xbongbong.pro.constant.DynamicManagerConstant;
import com.xbongbong.pro.domain.entity.AiAssistantEntity;
import com.xbongbong.pro.domain.entity.AiAssistantHistoryEntity;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.smartsettings.enums.SmartSettingsFieldEnum;
import com.xbongbong.pro.smartsettings.pojo.AddOrUpdateHistoryPojo;
import com.xbongbong.pro.smartsettings.pojo.LinkProductPojo;
import com.xbongbong.pro.smartsettings.pojo.SmartFieldAttrPojo;
import com.xbongbong.pro.smartsettings.pojo.SmartStrategyPojo;
import com.xbongbong.pro.smartsettings.pojo.SsExecutorPojo;
import com.xbongbong.pro.smartsettings.pojo.SsExecutorUserIdPojo;
import com.xbongbong.pro.smartsettings.pojo.SsMessageMergePojo;
import com.xbongbong.pro.smartsettings.pojo.dto.RunStrategyDTO;
import com.xbongbong.pro.smartsettings.pojo.dto.SmartStrategyRabbitMqDTO;
import com.xbongbong.pro.sms.pojo.SmsReceiverPojo;
import com.xbongbong.pro.sms.pojo.dto.SmsRabbitMqDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.SmsSetConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.ProductWarehouseEntity;
import com.xbongbong.saas.domain.entity.UserAndDepTeamEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.enums.BirthdayFilterEnum;
import com.xbongbong.saas.enums.ContractProduceEnum;
import com.xbongbong.saas.enums.SmsSendTypeEnum;
import com.xbongbong.saas.enums.SmsTemplateSendApiEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.model.AiAssistantHistoryModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.WarehouseUserModel;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author 吴峰
 * @date 2020/09/15 16:43
 */
@Component
public abstract class AbstractAiAssistantStrategyHandle {


    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAiAssistantStrategyHandle.class);
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private AiAssistantHistoryModel aiAssistantHistoryModel;
    @Resource
    private UserModel userModel;
    @Resource
    private UserAndDepartmentHelp userAndDepartmentHelp;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private WarehouseUserModel warehouseUserModel;
    @Resource
    private SsHistoryService ssHistoryService;
    @Resource
    private BusinessFeignClient businessFeignClient;
    @Resource
    private SsDistributeSaveService ssDistributeSaveService;
    @Resource
    private AiAssistantConditionHelp aiAssistantConditionHelp;
    @Resource
    private IndexTypeModel indexTypeModel;

    /**
     * 批量更新和插入
     * @param corpid
     * @param addList
     * @param updateList
     */
    protected void messageDataSave(String corpid, List<AiAssistantHistoryEntity> addList, List<AiAssistantHistoryEntity> updateList) {
        if (!addList.isEmpty()) {
            int count = addList.size();
            int start = 0;
            int pageNum = 1000;
            for (; start <= count; start = start + pageNum) {
                // 分组数据的endIndex
                int endIndex = (start + pageNum) <= count ? start + pageNum : count;
                List<AiAssistantHistoryEntity> subAddList = addList.subList(start, endIndex);
                if (!subAddList.isEmpty()) {
                    aiAssistantHistoryModel.insertBatch(subAddList);
                }
            }
        }
        // 批量更新记录
        if (!updateList.isEmpty()) {
            int count = updateList.size();
            int start = 0;
            int pageNum = 1000;
            for (; start <= count; start = start + pageNum) {
                // 分组数据的endIndex
                int endIndex = (start + pageNum) <= count ? start + pageNum : count;
                List<AiAssistantHistoryEntity> subUpdateList = updateList.subList(start, endIndex);
                if (!subUpdateList.isEmpty()) {
                    aiAssistantHistoryModel.updateBatch(subUpdateList, corpid);
                }
            }
        }
    }

    /**
     * 短信分发--记录入库
     *
     * @param formDataList     业务数据
     * @param addList 插入
     * @param updateList  更新
     * @param entity
     * @param isTest
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-05-17 15:35
     * @version v1.0
     * @since v1.0
     */
    protected void smsDistributeSave(List<PaasFormDataEntityExt> formDataList, List<AiAssistantHistoryEntity> addList, List<AiAssistantHistoryEntity> updateList,
                                     AiAssistantEntity entity, boolean isTest) {
        // saas只有客户可以发送短信，paas发送短信的字段为：单行文本&&手机类型
        Integer saasMark = entity.getSaasMark();
        String corpid = entity.getCorpid();
        // 电话map：{dataId:mobile}，名称map:{dataId:name}
        Map<Long, String> mobileMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, String> nameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<SmsReceiverPojo> receiverPojoList = new ArrayList<>();
        if (Objects.equals(SaasMarkEnum.SAAS.getCode(), saasMark)) {
            // 只有有电话的客户可以发送短信
            formDataList.forEach(item -> {
                JSONObject dataList = item.getData();
                String mobile = ssDistributeSaveService.getCustomerFirstMobile(dataList);
                String name = dataList.getString(CustomerManagementEnum.NAME.getAttr());
                if (Objects.nonNull(mobile)) {
                    mobileMap.put(item.getId(), mobile);
                    nameMap.put(item.getId(), name);

                    SmsReceiverPojo pojo = new SmsReceiverPojo(name, mobile);
                    receiverPojoList.add(pojo);
                }
            });
        } else if (Objects.equals(SaasMarkEnum.PAAS.getCode(), saasMark)) {
            JSONArray smsExecutorList = entity.getSmsExecutor();
            if (Objects.isNull(smsExecutorList) || smsExecutorList.isEmpty()) {
                return;
            }
            // 当前只取第一个字段，TODO 以后可扩展成手机多个字段
            SmartFieldAttrPojo executorAttr = smsExecutorList.getObject(0, SmartFieldAttrPojo.class);
            formDataList.forEach(item -> {
                JSONObject dataList = item.getData();
                String mobile = dataList.getString(executorAttr.getAttr());
                // TODO 标题是个列表，怎么玩；为了取到paas标题这个小小的数据，前期要准备好对应的表单、解释，不划算；还是使用mobile作为标题吧
                if (Objects.nonNull(mobile)) {

                    mobileMap.put(item.getId(), mobile);
                    nameMap.put(item.getId(), mobile);

                    SmsReceiverPojo pojo = new SmsReceiverPojo(mobile, mobile);
                    receiverPojoList.add(pojo);
                }
            });
        }


        String sendTime = getStrategyTime(entity);

        String placeholder = XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getName();
        String content = entity.getMemo();
        if (content.contains("{" + placeholder + "}")) {
            content = content.replaceAll("\\{" + placeholder + "\\}", I18nMessageUtil.getMessage(SmsSetConstant.SMS_RECEIVER_PLACE_HOLDER));
        }

        try {
            SmsRabbitMqDTO smsRabbitMqDTO = new SmsRabbitMqDTO();
            smsRabbitMqDTO.setCorpid(corpid);
            // 系统生成
            smsRabbitMqDTO.setUserId(PaasConstant.SYS_USER_ID);
            if (isTest) {
                smsRabbitMqDTO.setSendType(SmsSendTypeEnum.AT_ONCE.getCode());
            } else {
                smsRabbitMqDTO.setSendType(SmsSendTypeEnum.DELAY.getCode());
            }
            // 短信发送API类型
            smsRabbitMqDTO.setSendApi(SmsTemplateSendApiEnum.SPACE_IMAGINATION_NOTICE_AMOUNT.getCode());
            // 尊称无法传递，直接替换
            smsRabbitMqDTO.setContent(content);
            smsRabbitMqDTO.setDates(sendTime);
            smsRabbitMqDTO.setSendData(receiverPojoList);
            Locale locale = LocaleContextHolder.getLocale();
            String lang = locale.toString();
            String sendData = businessFeignClient.smsSend(smsRabbitMqDTO, lang);
            JSONObject resultObj = JsonHelperUtil.parseObject(sendData);
            if (ErrorCodeEnum.API_SUCCESS.getCode() != (int) resultObj.get(StringConstant.CODE)) {
                throw new XbbException(resultObj.getIntValue(StringConstant.CODE), resultObj.getString(StringConstant.KEY_ERROR_MSG));
            }
        } catch (XbbException e) {
            LOGGER.error("发送短信失败", e);
        }


        messageDataSave(corpid, addList, updateList);
    }

    /**
     * 获取智能助手执行时间
     *
     * @param entity
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-11-12 21:18
     * @version
     * @since
     */
    protected String getStrategyTime(AiAssistantEntity entity) {
        // 执行时间
        SmartStrategyPojo strategy = JSONObject.toJavaObject(entity.getStrategy(), SmartStrategyPojo.class);
        // 时分
        String timeStr = strategy.getStrategyTime();
        // 发送时间
        String sendTime = DateTimeUtil.getString(DateTimeUtil.SDFDate) + " " + timeStr;
        return sendTime;
    }
    /**
     * 获取待生产的合同数据
     * @param corpid 公司id
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-24 21:21
     * @since v1.0
     * @version v1.0
     */
    public Set<Long> getWaitProduceDataIds(String corpid) {
        Set<Long> waitProduceDataIdSet = new HashSet<>();
        List<ContractProductEntity> waitProduceProductList;
        try {
            waitProduceProductList = contractProductModel.getAllContractProduct(corpid, ContractProduceEnum.WAIT_PRODUCE.getCode());
        } catch (Exception e) {
            LOGGER.info("aiEs:getWaitProduceDataIds", e);
            waitProduceProductList = new ArrayList<>();
        }
        for (ContractProductEntity entity : waitProduceProductList) {
            waitProduceDataIdSet.add(entity.getContractId());
        }
        return waitProduceDataIdSet;
    }

    /**
     * 获取待采购的合同数据
     *
     * @param corpid 公司id
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-24 21:20
     * @since v1.0
     * @version v1.0
     */
    public Set<Long> getWaitPurchaseDataIds(String corpid) {
        Set<Long> waitPurchaseDataIdSet = new HashSet<>();
        List<ContractProductEntity> waitPurchaseProductList;
        try {
            waitPurchaseProductList = contractProductModel.getAllContractProduct(corpid, ContractProduceEnum.WAIT_PURCHASE.getCode());
        } catch (Exception e) {
            LOGGER.info("aiEs:getWaitPurchaseDataIds", e);
            waitPurchaseProductList = new ArrayList<>();
        }
        for (ContractProductEntity entity : waitPurchaseProductList) {
            //合同分组，拿合同id
            waitPurchaseDataIdSet.add(entity.getContractId());
        }
        return waitPurchaseDataIdSet;
    }

    /**
     * 获取执行人
     * @return
     */
    public abstract List<SsExecutorPojo> getExecutorUserList(AiAssistantEntity aiAssistantEntity, List<Long> dataIdList,
                                                       List<PaasFormDataEntityExt> formDataList);

    /**
     * 发送钉钉消息
     * @param aiAssistantEntity
     * @param messageMergeList
     * @param addList
     * @param updateList
     * @param dataList
     * @param runStrategyDTO
     */
    public abstract void sendDingTalkMessage(AiAssistantEntity aiAssistantEntity, List<SsMessageMergePojo>  messageMergeList, List<AiAssistantHistoryEntity> addList,
                                    List<AiAssistantHistoryEntity> updateList, List<PaasFormDataEntityExt> dataList, RunStrategyDTO runStrategyDTO);


    /**
     * 根据部门获取执行人
     * @param corpid
     * @param deptIds
     * @return
     */
    protected List<String> getExecUserIdByDept(String corpid, Set<Long> deptIds) {
        // 部门对应员工
        List<String> execUserIds = new ArrayList<>();
        Map<Long, List<String>> userIdsForDept = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (deptIds.size() > 0) {
            List<Map<String, Object>> userIdsForDepMapList = userModel.getUserIdsJoinDeptGroup(corpid, deptIds);
            for (Map<String, Object> userIdsForDepMap : userIdsForDepMapList) {
                Long depId = (Long) userIdsForDepMap.get("depId");
                String userIdsStr = (String) userIdsForDepMap.get("userIds");
                List<String> userIdList = StringUtil.toStringList(userIdsStr, StringConstant.COMMA);
                userIdsForDept.put(depId, userIdList);
            }
        }
        // 添加部门执行人
        if (!deptIds.isEmpty()) {
            for (Long depId : deptIds) {
                if (userIdsForDept.containsKey(depId)) {
                    execUserIds.addAll(userIdsForDept.get(depId));
                }
            }
        }
        return execUserIds;
    }
    /**
     * 根据角色获取执行人
     * @param corpid
     * @param roleIds
     * @return
     */
    protected List<String> getExecUserIdByRole(String corpid, Set<Integer> roleIds) {
        // 角色对应的员工
        List<String> execUserIds = new ArrayList<>();
        Map<Integer, List<String>> userIdsForRole = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (roleIds.size() > 0) {
            Map<Integer, List<String>> roleUserMap = userAndDepartmentHelp.userIdsForRole(corpid);
            for (Integer roleId : roleIds) {
                if (roleUserMap.containsKey(roleId)) {
                    userIdsForRole.put(roleId, roleUserMap.get(roleId));
                }
            }
        }
        // 添加角色执行人
        if ( !roleIds.isEmpty()) {
            for (Integer roleId : roleIds) {
                if (userIdsForRole.containsKey(roleId)) {
                    execUserIds.addAll(userIdsForRole.get(roleId));
                }
            }
        }
        return execUserIds;
    }

    /**
     * @param userTeamMap 员工团队map:{dataId: [userId1,userId2]}
     * @param userId      员工id
     * @param dataId      数据id
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-09 09:28
     * @version v1.0
     * @since v1.0
     */
    protected void setUserTeam(Map<Long, List<String>> userTeamMap, String userId, Long dataId) {
        if (userTeamMap.containsKey(dataId)) {
            List<String> userTeamIds = userTeamMap.get(dataId);
            userTeamIds.add(userId);
            userTeamMap.put(dataId, userTeamIds);
        } else {
            List<String> userTeamIds = new ArrayList<>();
            userTeamIds.add(userId);
            userTeamMap.put(dataId, userTeamIds);
        }
    }

    /**
     * @param aiAssistantEntity
     * @return com.xbongbong.pro.smartsettings.pojo.SsExecutorUserIdPojo
     * @author 吴峰
     * @date 2020/9/23 16:04
     * @throws XbbException       
     */
    protected SsExecutorUserIdPojo getExecUserIds(AiAssistantEntity aiAssistantEntity) {
        SsExecutorUserIdPojo ssExecutorUserIdPojo = new SsExecutorUserIdPojo();

        Set<String> execUserIds = new HashSet<>();
        String corpid = aiAssistantEntity.getCorpid();
        List<String> subAliasList = Arrays.asList(FieldTypeEnum.OWNERID.getAlias(), FieldTypeEnum.COUSERID.getAlias(), FieldTypeEnum.CREATORID.getAlias(),
                DynamicManagerConstant.LINK_CONTRACT_ALIAS, DynamicManagerConstant.LINK_WARE_HOUSE_ALIAS, DynamicManagerConstant.LINK_WARE_HOUSE_ALIAS);

        List<OptionalRangeEntity> rangeList = aiAssistantEntity.getExecutor().toJavaList(OptionalRangeEntity.class);
        // // 当前需要执行的人员

        Set<Long> deptIds = new HashSet<>();
        Set<Integer> roleIds = new HashSet<>();
        // 动态人员
        Set<Integer> managerLevels = new HashSet<>();
        Set<Integer> coordinatorLevels = new HashSet<>();
        Set<Integer> creatorLevels = new HashSet<>();
        // 关联合同
        Set<Integer> linkContractLevels = new HashSet<>();
        Set<Integer> linkWareHouseLevels = new HashSet<>();
        Set<Integer> linkPurchaseLevels = new HashSet<>();
        rangeList.forEach(rangeEntity -> {
            OptionalRangeEnum rangeEnum = OptionalRangeEnum.getByValue(rangeEntity.getProperty());
            String attrAlias = rangeEntity.getAttr();

            if (subAliasList.contains(attrAlias)) {
                // 动态负责人
                Integer code = Integer.parseInt(rangeEntity.getId());
                if (Objects.equals(FieldTypeEnum.OWNERID.getAlias(), attrAlias)) {
                    managerLevels.add(code);
                } else if (Objects.equals(FieldTypeEnum.COUSERID.getAlias(), attrAlias)) {
                    coordinatorLevels.add(code);
                } else if (Objects.equals(FieldTypeEnum.CREATORID.getAlias(), attrAlias)) {
                    creatorLevels.add(code);
                } else if (Objects.equals(DynamicManagerConstant.LINK_CONTRACT_ALIAS, attrAlias)) {
                    linkContractLevels.add(code);
                } else if (Objects.equals(DynamicManagerConstant.LINK_WARE_HOUSE_ALIAS, attrAlias)) {
                    linkWareHouseLevels.add(code);
                } else if (Objects.equals(DynamicManagerConstant.LINK_PURCHASE_ALIAS, attrAlias)) {
                    linkPurchaseLevels.add(code);
                }
            } else if (rangeEnum != null) {
                switch (rangeEnum) {
                    case DEPT:
                        Long deptId = Long.parseLong(rangeEntity.getId());
                        deptIds.add(deptId);
                        break;
                    case USER:
                        execUserIds.add(rangeEntity.getId());
                        break;
                    case ROLE:
                        Integer roleId = Integer.parseInt(rangeEntity.getId());
                        roleIds.add(roleId);
                        break;
                    default:
                        break;
                }
            }
        });
        // 根据部门获取执行人
        execUserIds.addAll(getExecUserIdByDept(corpid, deptIds));
        // 根据角色获取执行人
        execUserIds.addAll(getExecUserIdByRole(corpid, roleIds));
        // 执行人
        ssExecutorUserIdPojo.setExecUserIds(execUserIds);
        // 动态执行人
        ssExecutorUserIdPojo.setCoordinatorLevels(coordinatorLevels);
        ssExecutorUserIdPojo.setCreatorLevels(creatorLevels);
        ssExecutorUserIdPojo.setManagerLevels(managerLevels);
        return ssExecutorUserIdPojo;
    }

    /**
     * 获取关联合同的负责人ids
     *
     * @param formDataList 数据列表
     * @param aiAssistantEntity 智能助手
     * @return 回款计划对应合同负责人（付款计划对应的采购合同负责人）的userIds
     * @throws
     * @author 吴峰
     * @date 2020/9/18 10:24
     * @version v1.0
     * @since v1.0
     */
    protected Map<Long, Set<String>> getLinkContrOrPurUserIds(List<PaasFormDataEntityExt> formDataList, AiAssistantEntity aiAssistantEntity) {
        Map<Long, Set<String>> userMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Integer businessType = aiAssistantEntity.getBusinessType();
        String corpid = aiAssistantEntity.getCorpid();
        if (Objects.equals(XbbRefTypeEnum.PAYMENT.getCode(),  businessType) || Objects.equals(XbbRefTypeEnum.PAY_PLAN.getCode(), businessType)) {
            // 回款id对应合同id的map
            Set<Long> contractIdSet = new HashSet<>();

            // 关联的合同/采购合同类型
            Integer linkBusinessType = XbbRefTypeEnum.CONTRACT.getCode();

            String attr = PaymentEnum.CONTRACT.getAttr();
            if (Objects.equals(XbbRefTypeEnum.PAY_PLAN.getCode(), businessType)) {
                attr = PayPlanEnum.LINK_PURCHASE.getAttr();
                linkBusinessType = XbbRefTypeEnum.PURCHASE.getCode();
            }
            // 获取对应的合同/采购合同
            for (PaasFormDataEntityExt entityExt : formDataList) {
                JSONObject dataList = entityExt.getData();
                Long contractId = dataList.getLong(attr);
                if (Objects.nonNull(contractId)) {
                    contractIdSet.add(contractId);
                }
            }

            List<UserTeamEntity> userTeamList = userTeamHelp.getUserTeamList(contractIdSet, corpid, linkBusinessType, false, 1);
            userTeamList.forEach(item -> {
                Long dataId = item.getDataId();
                if (userMap.containsKey(dataId)) {
                    userMap.get(dataId).add(item.getUserId());
                } else {
                    Set<String> userList = new HashSet<>();
                    userList.add(item.getUserId());
                    userMap.put(dataId, userList);
                }
            });
        }
        return userMap;
    }

    /**
     * 获取关联仓库的负责人id
     * @param formDataList
     * @param aiAssistantEntity
     * @return
     */
    protected Map<Long, Set<String>> getLinkWarehouseUserId(List<PaasFormDataEntityExt> formDataList, AiAssistantEntity aiAssistantEntity) {
        Integer businessType = aiAssistantEntity.getBusinessType();
        String corpid = aiAssistantEntity.getCorpid();
        XbbRefTypeEnum refTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        LinkProductPojo linkProductPojo = new LinkProductPojo();

        switch (refTypeEnum) {
            case CONTRACT:
                linkProductPojo = getLinkProduct(formDataList, ContractEnum.PRODUCT.getAttr());
                break;
            case PURCHASE:
                linkProductPojo = getLinkProduct(formDataList, PurchaseEnum.PRODUCT.getAttr());
                break;
            case PRODUCTION_ORDER:
                linkProductPojo = getLinkProduct(formDataList, ProductionOrderEnum.PRODUCT.getAttr());
                break;
            case PRODUCT:
                linkProductPojo = getLinkProduct(formDataList, "");
                break;
            default:
                break;
        }
        Set<Long> productIdList = linkProductPojo.getProductIdSet();
        Map<Long, Set<Long>> productIdMap = linkProductPojo.getProductIdMap();
        // 业务数据对应关联产品的负责人
        Map<Long, Set<String>> dataUserIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionsUtil.isNotEmpty(productIdList)) {
            // 产品对应的产品仓库
            List<ProductWarehouseEntity> productWarehouseList = getProductWarehouseList(corpid, productIdList);
            // 产品对应的产品库存ids, 产品库存ids，库存对应的负责人ids
            Map<Long, Set<Long>> productIdWarehouseIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Set<Long> warehouseIdSet = new HashSet<>();


            if (Objects.nonNull(productWarehouseList) && !productWarehouseList.isEmpty()) {
                for (ProductWarehouseEntity warehouse : productWarehouseList) {
                    Long productId = warehouse.getProductId();
                    warehouseIdSet.add(warehouse.getId());
                    if (productIdWarehouseIdsMap.containsKey(productId)) {
                        Set<Long> warehouseIds = productIdWarehouseIdsMap.get(productId);
                        warehouseIds.add(warehouse.getId());
                        productIdWarehouseIdsMap.put(productId, warehouseIds);
                    } else {
                        Set<Long> warehouseIds = new HashSet<>();
                        warehouseIds.add(warehouse.getId());
                        productIdWarehouseIdsMap.put(productId, warehouseIds);
                    }
                }
            }

            Map<Long, Set<String>> warehouseUserMap = getWarehouseUser(warehouseIdSet, corpid);

            // 库存负责人--> 产品对应的库存负责人 --> 合同/采购合同/生产单对应的库存负责人
            if (!warehouseUserMap.isEmpty()) {
                // 产品对应的库存负责人
                Map<Long, Set<String>> productUserIdsMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for (Map.Entry<Long, Set<Long>> productWarehouseEntry : productIdWarehouseIdsMap.entrySet()) {
                    Set<Long> warehouseIds = productWarehouseEntry.getValue();
                    Long productId = productWarehouseEntry.getKey();
                    for (Map.Entry<Long, Set<String>> entry : warehouseUserMap.entrySet()) {
                        Long warehouseId = entry.getKey();
                        Set<String> userIds = entry.getValue();
                        if (!warehouseIds.contains(warehouseId)) {
                            continue;
                        }
                        if (productUserIdsMap.containsKey(productId)) {
                            productUserIdsMap.get(productId).addAll(userIds);
                        } else {
                            productUserIdsMap.put(productId, userIds);
                        }
                    }
                }
                for (Map.Entry<Long, Set<Long>> entry : productIdMap.entrySet()) {
                    Long dataId = entry.getKey();
                    Set<Long> productIds = entry.getValue();
                    // 负责人Set
                    Set<String> userIds = new HashSet<>();

                    for (Map.Entry<Long, Set<String>> userIdsMapEntry : productUserIdsMap.entrySet()) {
                        if (productIds.contains(userIdsMapEntry.getKey())) {
                            // 根据产品id拿到对应的仓库负责人
                            userIds.addAll(userIdsMapEntry.getValue());
                        }
                    }
                    dataUserIdsMap.put(dataId, userIds);

                }
            }
        }
        return dataUserIdsMap;
    }

    /**
     * 获取仓库对应的仓库负责人
     * @param warehouseIdSet 仓库id
     * @param corpid 公司id
     * @return
     */
    public Map<Long, Set<String>> getWarehouseUser(Set<Long> warehouseIdSet, String corpid) {
        Map<Long, Set<String>> warehouseUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!warehouseIdSet.isEmpty()) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            // type=0时relationId为员工Id
            param.put("type", BasicConstant.ZERO);
            param.put("del", DelEnum.NORMAL.getDel());

            List<UserAndDepTeamEntity> userAndDepTeamEntityList = new ArrayList<>();
            // 分页查询
            List<Long> allWarhouseIdList = new ArrayList<>(warehouseIdSet);
            int count = allWarhouseIdList.size();
            int start = 0;
            int pageNum = 2000;
            for (; start <= count; start = start + pageNum) {
                // 分组数据的endIndex
                int endIndex = (start + pageNum) <= count ? start + pageNum : count;
                List<Long> subWarhouseIdList = allWarhouseIdList.subList(start, endIndex);
                param.put("warehouseIdIn", subWarhouseIdList);
                List<UserAndDepTeamEntity> list = warehouseUserModel.findBaseEntitys(param);
                userAndDepTeamEntityList.addAll(list);
            }

            for (UserAndDepTeamEntity entity : userAndDepTeamEntityList) {
                if (Objects.equals(entity.getType(), BasicConstant.ZERO)) {
                    Long warehouseId = entity.getDataId();
                    if (warehouseUserMap.containsKey(warehouseId)) {
                        warehouseUserMap.get(warehouseId).add(entity.getRelationId());
                    } else {
                        Set<String> wareUserIdSet = new HashSet<>();
                        wareUserIdSet.add(entity.getRelationId());
                        warehouseUserMap.put(warehouseId, wareUserIdSet);
                    }
                }
            }
        }
        return warehouseUserMap;
    }

    /**
     * 获取产品库存
     * @param corpid
     * @param productIdList
     * @return
     */
    private List<ProductWarehouseEntity> getProductWarehouseList(String corpid , Set<Long> productIdList) {
        List<ProductWarehouseEntity> productWarehouseList = new ArrayList<>();
        if (CollectionsUtil.isEmpty(productIdList)) {
            return productWarehouseList;
        }
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery("productId", productIdList));
        boolQueryBuilder.filter(termQuery("warehouseChecked", 1));
        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.DATA_ID);
        try {
            productWarehouseList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT_WAREHOUSE, boolQueryBuilder, ProductWarehouseEntity.class, fieldList);
        } catch (XbbException e) {
            LOGGER.error("获取产品库存失败：", e);
        }
        return productWarehouseList;
    }

    /**
     * 获取关联的产品id
     *
     * @param formDataList 业务数据列表
     * @param attr         关联产品的attr
     * @return 返回关联产品id或者产品的id
     * @author 吴峰
     * @date 2020/9/18 10:55
     * @version v1.0
     * @since v1.0
     */
    private LinkProductPojo getLinkProduct(List<PaasFormDataEntityExt> formDataList, String attr) {
        Set<Long> dataIdSet = new HashSet<>();
        LinkProductPojo linkProductPojo = new LinkProductPojo();
        if (Objects.isNull(formDataList) || formDataList.isEmpty()) {
            return linkProductPojo;
        }
        Map<Long, Set<Long>> productIdMap = new HashMap<>(formDataList.size());
        Set<Long> productIdSet = new HashSet<>();
        for (PaasFormDataEntityExt entityExt : formDataList) {
            Long dataId = entityExt.getId();
            JSONObject dataList = entityExt.getData();
            if (attr.isEmpty()) {
                dataIdSet.add(dataId);
                productIdSet.clear();
                productIdSet.add(dataId);
                productIdMap.put(dataId, productIdSet);
            } else if (CollectionsUtil.isNotEmpty(dataList.getJSONArray(attr))) {
                // 所有的产品id
                List<Long> productIds = dataList.getJSONArray(attr).toJavaList(Long.class);
                dataIdSet.addAll(productIds);
                productIdSet.clear();
                productIdSet.addAll(productIds);
                productIdMap.put(dataId, productIdSet);
            }

        }
        linkProductPojo.setProductIdMap(productIdMap);
        linkProductPojo.setProductIdSet(productIdSet);
        return linkProductPojo;
    }

    /**
     * 根据智能助手条件获取数据
     * @param rabbitMqDTO
     * @return
     */
    protected List<Long> getDataIds(SmartStrategyRabbitMqDTO rabbitMqDTO) {
        // 查询条件准备
        AiAssistantEntity aiAssistantEntity = rabbitMqDTO.getAiAssistantEntity();
        String corpid = rabbitMqDTO.getCorpid();


        List<ConditionsEntityExt> allConditionList = new ArrayList<>();
        List<ConditionsEntityExt> conditionList = aiAssistantEntity.getTriggerCondition().toJavaList(ConditionsEntityExt.class);
        allConditionList.addAll(conditionList);

        // 获取是否有关联数据查询的触发条件
        Map<String, Boolean> linkDataFlagMap = aiAssistantConditionHelp.getLinkDataFlag(allConditionList);

        Set<Long> waitPurchaseDataIdSet = new HashSet<>();
        Set<Long> waitProduceDataIdSet = new HashSet<>();
        // 待生产
        if (linkDataFlagMap.containsKey(SmartSettingsFieldEnum.WAIT_PRODUCTION_ORDER.getAlias())) {
            waitProduceDataIdSet = getWaitProduceDataIds(corpid);
        }
        // 待采购
        if (linkDataFlagMap.containsKey(SmartSettingsFieldEnum.WAIT_PURCHASE.getAlias())) {
            waitPurchaseDataIdSet = getWaitPurchaseDataIds(corpid);
        }

        // 通用筛选条件
        conditionList = new ArrayList<>();
        // 产品下限预警、产品保质期预警
        List<ConditionsEntityExt> stockWarningConditionList = new ArrayList<>();
        List<ConditionsEntityExt> expireWarningConditionList = new ArrayList<>();
        // 生日筛选条件
        List<ConditionsEntityExt> birthdayConditionList = new ArrayList<>();
        List<Long> dataIds = new ArrayList<>();
        // 工作报告不处理
        // 添加筛选条件
        aiAssistantConditionHelp.addConditionList(aiAssistantEntity, conditionList, birthdayConditionList, stockWarningConditionList, expireWarningConditionList, waitProduceDataIdSet, waitPurchaseDataIdSet);
        if (conditionList.isEmpty() && stockWarningConditionList.isEmpty() && expireWarningConditionList.isEmpty() && birthdayConditionList.isEmpty()) {
           return new ArrayList<>();
        }
        int saasMark = aiAssistantEntity.getSaasMark();
        // es查询
        BoolQueryBuilder boolQueryBuilder = boolQuery();

        List<String> fieldList = new ArrayList<>();
        fieldList.add(StringConstant.DATA_ID);
        try {
            // 筛选条件
            if (!conditionList.isEmpty()) {
                EsUtil.parseCondition(boolQueryBuilder, conditionList, "", corpid, aiAssistantEntity.getBusinessType());
            }
            // 生日特殊处理
            if (!birthdayConditionList.isEmpty()) {
                Integer day = 0;
                for(ConditionsEntityExt conditionsEntityExt : birthdayConditionList) {
                    try {
                        List<Object> valueList = conditionsEntityExt.getValue();
                        if(!valueList.isEmpty()) {
                            day = Integer.valueOf(valueList.get(0).toString());
                        }
                    } catch (NumberFormatException e) {
                        day = 0;
                    }
                    EsUtil.conditionBirthday(boolQueryBuilder, BirthdayFilterEnum.REMIND.getValue(), day, aiAssistantEntity.getBusinessType());
                }
            }
            // 产品下限/上限预警
            if (!stockWarningConditionList.isEmpty()) {
                EsUtil.parseProductSearchCondition(boolQueryBuilder, stockWarningConditionList, "", corpid, XbbRefTypeEnum.WARNING_SEARCH.getCode());
            }
            // 产品保质期预警
            if (!expireWarningConditionList.isEmpty()) {
                EsUtil.parseProductSearchCondition(boolQueryBuilder, expireWarningConditionList, "", corpid, XbbRefTypeEnum.GUARANTEE_SEARCH.getCode());
            }
        } catch (XbbException e) {
            return new ArrayList<>();
        }

        // 添加corpid,formId,del
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("formId", aiAssistantEntity.getFormId()));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        //无需审批和通过
        boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.getStatisticType()));


        List<PaasFormDataEntityExt> dataList = new ArrayList<>();
        try {
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(corpid, aiAssistantEntity.getBusinessType(), saasMark);
            XbbAggregatedPage<PaasFormDataEntityExt> aggregatedPage = esHelper.findByPage(indexTypeEnum, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList, 1,
                    SizeConstant.AI_ASSISTANT_MAX_PAGE_SIZE, new ArrayList<>());
            if (Objects.nonNull(aggregatedPage)) {
                dataList = aggregatedPage.getContent();
            }
            if (dataList.size() >= SizeConstant.AI_ASSISTANT_MAX_PAGE_SIZE) {
                LOGGER.info("corpid：" + corpid + "检索的数据量大于等于" + SizeConstant.AI_ASSISTANT_MAX_PAGE_SIZE + "，不在执行策略：" + aiAssistantEntity.getName() + "；策略id：" + aiAssistantEntity.getId());
                return new ArrayList<>();
            }
            if (dataList.size() > 0) {
                dataList.forEach(item -> {
                    dataIds.add(item.getDataId());
                });
            }
        } catch (XbbException e) {
            LOGGER.error("aiEs:dataList", e);
            return new ArrayList<>();
        }
        return dataIds;

    }

    /**
     * 对历史记录以及执行次数进行整理
     * @param historyList
     * @param dataIdList
     * @param aiAssistantEntity
     * @return com.xbongbong.pro.smartsettings.pojo.AddOrUpdateHistoryPojo 返回新增和编辑的历史记录
     * @author 吴峰
     * @date 2020/9/24 17:04
     * @throws XbbException
     */
    protected AddOrUpdateHistoryPojo getAddOrUpdateList(List<AiAssistantHistoryEntity> historyList, List<Long> dataIdList, AiAssistantEntity aiAssistantEntity) {
        AddOrUpdateHistoryPojo addOrUpdateHistoryPojo = new AddOrUpdateHistoryPojo();
        List<AiAssistantHistoryEntity> addList = new ArrayList<>();
        List<AiAssistantHistoryEntity> updateList = new ArrayList<>();
        if (CollectionsUtil.isEmpty(historyList)) {
            addList = ssHistoryService.getAddHistoryList(dataIdList, aiAssistantEntity);
        } else {
            Map<Long, AiAssistantHistoryEntity> aiAssistantHistoryMap = new HashMap<>(historyList.size());
            historyList.forEach(item->{
                aiAssistantHistoryMap.put(item.getDataId(), item);
            });
            for (Long dataId : dataIdList) {
                if (aiAssistantHistoryMap.containsKey(dataId)) {
                    JSONObject strategy = aiAssistantEntity.getStrategy();
                    AiAssistantHistoryEntity history = aiAssistantHistoryMap.get(dataId);
                    Integer strategyNum = strategy.getInteger("strategyNum") == null ? 0 : strategy.getInteger("strategyNum");
                    Integer triggerNum = history.getTriggerNum();
                    if (history.getTriggerNum() >= strategyNum) {
                        // 智能助手执行次数大于等于记录次数时，不在执行
                        continue;
                    }
                    triggerNum++;
                    history.setTriggerNum(triggerNum);
                    updateList.add(history);
                } else {
                    AiAssistantHistoryEntity historyEntity = new AiAssistantHistoryEntity();
                    BeanUtil.copyProperties(aiAssistantEntity, historyEntity);
                    historyEntity.setId(null);
                    historyEntity.setDataId(dataId);
                    historyEntity.setAiAssistantId(aiAssistantEntity.getId());
                    addList.add(historyEntity);
                }
            }
        }
        addOrUpdateHistoryPojo.setAddList(addList);
        addOrUpdateHistoryPojo.setUpdateList(updateList);
        return addOrUpdateHistoryPojo;
    }


    /**
     * 根据查询到数据id去查询历史记录
     * @param dataIdList
     * @param corpid
     * @param aiAssistantId
     * @return
     */
    public List<AiAssistantHistoryEntity> getHistoryList(List<Long> dataIdList, String corpid, Long aiAssistantId){
        if (CollectionsUtil.isEmpty(dataIdList)) {
            new ArrayList<>();
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put("dataIdIn", dataIdList);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("aiAssistantId", aiAssistantId);
        param.put("columns", "id,corpid,ai_assistant_id,saas_mark,business_type,form_id,data_id,action, SUM(trigger_num) AS trigger_num,trigger_invalid,add_time,update_time,del,time_and_executor");
        param.put("groupByStr", "data_id");
        List<AiAssistantHistoryEntity> list = aiAssistantHistoryModel.findEntitys(param);
        if (CollectionsUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list;
    }
}
